home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / Color Picker SDK / Sample Code / ScrapPicker Sample / Sources ƒ / PickerCommonUtils.c < prev    next >
Encoding:
Text File  |  1997-06-13  |  9.9 KB  |  493 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        PickerCommonUtils.c
  3.     Copyright:    © 1996-1997 by Apple Computer, Inc., all rights reserved.
  4. */
  5.  
  6.  
  7. //===============================================================================
  8. //
  9. //                                 PickerCommonUtils.c
  10. //
  11. //===============================================================================
  12.  
  13.  
  14. #include <ColorPicker.h>
  15. #include <Resources.h>
  16. #include <TextUtils.h>
  17. #include <ToolUtils.h>
  18. #include "PickerCommon.h"
  19.  
  20.  
  21. #ifdef COMPONENT_SIGNATURE
  22. #undef COMPONENT_SIGNATURE
  23. #endif
  24. #define COMPONENT_SIGNATURE        'pcmn'
  25.  
  26.  
  27.                 // Reserve size for SmartNewHandle() and SmartNewPtr() .
  28. #define kMemReserve                32767
  29.  
  30.                 // Return values for ChooseHeap().
  31. enum
  32. {
  33.     noHeap = 0,
  34.     currentHeap,
  35.     systemHeap,
  36.     tempHeap
  37. };
  38.  
  39.  
  40. static long ChooseHeap (Size, Size);
  41. static OSErr GetZoneSizes (Size *, Size *, Size *);
  42. static long LargestHeap (Size, Size, Size);
  43. static void SetMem (void *, Size, UInt8);
  44.  
  45.  
  46. //===================================================================== Functions
  47. //--------------------------------------------------------------------- PasStringCopy
  48.  
  49. void PasStringCopy (StringPtr p1, StringPtr p2)
  50. {
  51.     register short        stringLength;
  52.     
  53.     stringLength = *p2++ = *p1++;
  54.     while (--stringLength >= 0)
  55.         *p2++ = *p1++;
  56. }
  57.  
  58. //--------------------------------------------------------------------- HappiNewHandle
  59.  
  60. Handle HappiNewHandle (Size byteCount, OSErr *resultErr)
  61. {
  62.     Handle        theHandle;
  63.     short        whichHeap;
  64.     OSErr        theErr;
  65.     
  66.     whichHeap = ChooseHeap(byteCount, kMemReserve);
  67.     
  68.     switch (whichHeap)
  69.     {
  70.         case noHeap:
  71.         theHandle = 0L;
  72.         theErr = memFullErr;
  73.         break;
  74.         
  75.         case currentHeap:
  76.         theHandle = NewHandle(byteCount);
  77.         theErr = MemError();
  78.         break;
  79.         
  80.         case systemHeap:
  81.         theHandle = NewHandleSys(byteCount);
  82.         theErr = MemError();
  83.         break;
  84.         
  85.         case tempHeap:
  86.         theHandle = TempNewHandle(byteCount, &theErr);
  87.         break;
  88.         
  89.                 // Error in ChooseHeap()
  90.         default:
  91.         theHandle = 0L;
  92.         theErr = paramErr;
  93.         break;
  94.     }
  95.     
  96.     if (!theErr && !theHandle)
  97.         theErr = memFullErr;
  98.     
  99.     if (theErr && theHandle)
  100.         theHandle = 0L;
  101.     
  102.     if (resultErr)
  103.         *resultErr = theErr;
  104.     
  105.     check((theErr == noErr) && (theHandle));
  106.     
  107.     return theHandle;
  108. }
  109.  
  110. //---------------------------------------------------------------------  HappiNewHandleClear
  111.  
  112. Handle HappiNewHandleClear (Size byteCount, OSErr *resultErr)
  113. {
  114.     Handle        theHandle;
  115.     short        whichHeap;
  116.     OSErr        theErr;
  117.     
  118.     whichHeap = ChooseHeap(byteCount, kMemReserve);
  119.     
  120.     switch (whichHeap)
  121.     {
  122.         case noHeap:
  123.             theHandle = 0L;
  124.             theErr = memFullErr;
  125.             break;
  126.         
  127.         case currentHeap:
  128.             theHandle = NewHandleClear(byteCount);
  129.             theErr = MemError();
  130.             break;
  131.         
  132.         case systemHeap:
  133.             theHandle = NewHandleSysClear(byteCount);
  134.             theErr = MemError();
  135.             break;
  136.         
  137.         case tempHeap:
  138.             theHandle = TempNewHandle(byteCount, &theErr);
  139.             if (theHandle && !theErr)
  140.                 SetMem( *theHandle, byteCount, 0x00);
  141.             break;
  142.         
  143.         default:                            /* Error in ChooseHeap(…) */
  144.             theHandle = 0L;
  145.             theErr = paramErr;
  146.             break;
  147.     }
  148.     
  149.     if (!theErr && !theHandle)
  150.         theErr = memFullErr;
  151.     
  152.     if (theErr && theHandle )
  153.         theHandle = 0L;
  154.     
  155.     if (resultErr)
  156.         *resultErr = theErr;
  157.     
  158.     check((theErr == noErr) && (theHandle));
  159.     
  160.     return theHandle;
  161. }
  162.  
  163. //--------------------------------------------------------------------- HappiNewPointer
  164.  
  165. Ptr HappiNewPointer (Size byteCount, OSErr *resultErr)
  166. {
  167.     Ptr            thePointer;
  168.     SInt16        whichHeap;
  169.     OSErr        theErr;
  170.     
  171.     whichHeap = ChooseHeap(byteCount, kMemReserve);
  172.     
  173.     switch (whichHeap)
  174.     {
  175.         case noHeap:
  176.         thePointer = 0L;
  177.         theErr = memFullErr;
  178.         break;
  179.         
  180.         case currentHeap:
  181.         thePointer = NewPtr(byteCount);
  182.         theErr = MemError();
  183.         break;
  184.         
  185.                 // System heap is growable into temp zone.
  186.         case systemHeap:
  187.         case tempHeap:
  188.         thePointer = NewPtrSys(byteCount);
  189.         theErr = MemError();
  190.         break;
  191.         
  192.                 // Error in ChooseHeap().
  193.         default:
  194.         thePointer = 0L;
  195.         theErr = paramErr;
  196.         break;
  197.     }
  198.     
  199.     if (!theErr && !thePointer)
  200.         theErr = memFullErr;
  201.     
  202.     if (theErr && thePointer)
  203.         thePointer = 0L;
  204.     
  205.     if (resultErr)
  206.         *resultErr = theErr;
  207.     
  208.     check((theErr == noErr) && (thePointer));
  209.     
  210.     return thePointer;
  211. }
  212.  
  213. //--------------------------------------------------------------------- HappiNewPointerClear
  214.  
  215. Ptr HappiNewPointerClear (Size byteCount, OSErr *resultErr)
  216. {
  217.     Ptr            thePointer;
  218.     SInt16        whichHeap;
  219.     OSErr        theErr;
  220.     
  221.     whichHeap = ChooseHeap(byteCount, kMemReserve);
  222.     
  223.     switch (whichHeap)
  224.     {
  225.         case noHeap:
  226.         thePointer = 0L;
  227.         theErr = memFullErr;
  228.         break;
  229.         
  230.         case currentHeap:
  231.         thePointer = NewPtrClear(byteCount);
  232.         theErr = MemError();
  233.         break;
  234.         
  235.                 // System heap is growable into temp zone.
  236.         case systemHeap:
  237.         case tempHeap:
  238.         thePointer = NewPtrSysClear(byteCount);
  239.         theErr = MemError();
  240.         break;
  241.         
  242.                 // Error in ChooseHeap().
  243.         default:
  244.         thePointer = 0L;
  245.         theErr = paramErr;
  246.         break;
  247.     }
  248.     
  249.     if (!theErr && !thePointer)
  250.         theErr = memFullErr;
  251.     
  252.     if (theErr && thePointer)
  253.         thePointer = 0L;
  254.     
  255.     if (resultErr)
  256.         *resultErr = theErr;
  257.     
  258.     check((theErr == noErr) && (thePointer));
  259.     
  260.     return thePointer;
  261. }
  262.  
  263. //--------------------------------------------------------------------- HappiGetResource
  264.  
  265. Handle HappiGetResource (ResType theType, SInt16 theID, OSErr *resultErr)
  266. {
  267.     Handle        theResource;
  268.     Handle        resultingHandle;
  269.     Size        byteCount;
  270.     SInt16        whichHeap;
  271.     OSErr        theErr;
  272.     
  273.                 // We don't want to load the resource, just get its size.
  274.     SetResLoad(false);
  275.     theResource = GetResource(theType, theID);
  276.     theErr = ResError();
  277.     SetResLoad(true);
  278.     require(theErr == noErr, bail);
  279.     
  280.                 // Get resource size.
  281.     byteCount = GetMaxResourceSize(theResource);
  282.     
  283.                 // Determine which heap can fit the resource.
  284.     whichHeap = ChooseHeap(byteCount, kMemReserve);
  285.     
  286.     switch (whichHeap)
  287.     {
  288.         case noHeap:
  289.         resultingHandle = 0L;
  290.         theErr = memFullErr;
  291.         break;
  292.         
  293.         case currentHeap:
  294.         resultingHandle = GetResource(theType, theID);
  295.         require_action(resultingHandle, bail, theErr = ResError(););
  296.         DetachResource(resultingHandle);
  297.         theErr = ResError();
  298.         break;
  299.         
  300.                 // System heap is growable into temp zone.
  301.         case systemHeap:
  302.         case tempHeap:
  303.         
  304.                 // Create a handle in temp mem.
  305.         resultingHandle = TempNewHandle(byteCount, &theErr);
  306.         require(resultingHandle, bail);
  307.         
  308.                 // Load the resource data into it.
  309.         HLockHi(resultingHandle);
  310.         ReadPartialResource(theResource, 0L, (*resultingHandle), byteCount);
  311.         theErr = ResError();
  312.         HUnlock(resultingHandle);
  313.         break;
  314.         
  315.                 // Error in ChooseHeap().
  316.         default:
  317.         resultingHandle = 0L;
  318.         theErr = paramErr;
  319.         break;
  320.     }
  321.     
  322. bail:
  323.     
  324.     if (!theErr && !resultingHandle)
  325.         theErr = memFullErr;
  326.     
  327.     if (theErr)
  328.         resultingHandle = 0L;
  329.     
  330.     if (resultErr)
  331.         *resultErr = theErr;
  332.     
  333.     check((theErr == noErr) && (resultingHandle));
  334.     
  335.     return resultingHandle;
  336. }
  337.  
  338.  
  339. #define MinFix(a,b)        ( ((a)<(b))?(a):(b) )
  340. #define MaxFix(a,b)        ( ((a)>(b))?(a):(b) )
  341. #define HighWord(x)        ( (unsigned long)x>>16 )
  342.  
  343.  
  344. #pragma mark -------------------- Private Functions
  345. //===================================================================== Private Functions
  346. //--------------------------------------------------------------------- ChooseHeap
  347.  
  348. static long ChooseHeap (Size bytesNeeded, Size reserve)
  349. {
  350.     OSErr    theErr;
  351.     short    whichHeap;
  352.     Size    currZoneTotalFree;
  353.     Size    sysZoneTotalFree;
  354.     Size    tempZoneTotalFree;
  355.     
  356.     theErr = GetZoneSizes(&currZoneTotalFree, &sysZoneTotalFree, &tempZoneTotalFree);
  357.     
  358.     if (theErr)
  359.         whichHeap = noHeap;
  360.     else
  361.     {
  362.         bytesNeeded += reserve;
  363.         
  364.         if (tempZoneTotalFree >= bytesNeeded)
  365.         {
  366.                 // First, the Process Manager temp zone.
  367.             whichHeap = tempHeap;
  368.         }
  369.         else if (currZoneTotalFree >= bytesNeeded)
  370.         {
  371.                 // Second, the current zone.
  372.             whichHeap = currentHeap;
  373.             DebugStr("\pCurrent Heap");
  374.         }
  375.         else if (sysZoneTotalFree >= bytesNeeded)
  376.         {
  377.                 // Third, the system zone (we assert because these are desparate times).
  378.             whichHeap = systemHeap;
  379.             DebugStr("\pSys Heap");
  380.         }
  381.         else
  382.         {
  383.                 // If we can't leave reserve, select the biggest heap.
  384.                 // (we assert because these are desparate times)
  385.             whichHeap = LargestHeap(currZoneTotalFree, sysZoneTotalFree, tempZoneTotalFree);
  386.             DebugStr("\pLargest Heap");
  387.         }
  388.     }
  389.     
  390.     return whichHeap;
  391. }
  392.  
  393. //--------------------------------------------------------------------- GetZoneSizes
  394.  
  395. static OSErr GetZoneSizes (Size *currZoneTotalFree, Size *sysZoneTotalFree, 
  396.         Size *tempZoneTotalFree)
  397. {
  398.     OSErr        theErr;
  399.     Boolean        currZoneIsSysZone;
  400.     
  401.                 // Init for error handling.
  402.     theErr = noErr;
  403.     
  404.                 // See if the current zone is the System Zone.
  405.     currZoneIsSysZone = (GetZone() == SystemZone());
  406.     theErr = MemError();
  407.     check(theErr == noErr);
  408.     
  409.     if (!theErr)
  410.     {
  411.                 // Free space in current zone.
  412.         *currZoneTotalFree = MaxBlock();
  413.         theErr = MemError();
  414.         check(theErr == noErr);
  415.     }
  416.     
  417.     if (!theErr)
  418.     {
  419.                 // Free space in System zone.
  420.         if (currZoneIsSysZone)
  421.         {
  422.             *sysZoneTotalFree = *currZoneTotalFree;
  423.         }
  424.         else
  425.         {
  426.             *sysZoneTotalFree = MaxBlockSys();
  427.             theErr = MemError();
  428.             check(theErr == noErr);
  429.         }
  430.     }
  431.     
  432.     if (!theErr)
  433.     {
  434.                 // Free space in Process Manager temp zone.
  435.                 // !! this assumes that the _OSDispatch trap is available
  436.                 // !! i.e. that this code isnt being called at init-time.
  437.         Size        grow;
  438.         
  439.         *tempZoneTotalFree = TempMaxMem(&grow);
  440.         theErr = MemError();
  441.         check(theErr == noErr);
  442.     }
  443.     
  444.     if (theErr)
  445.         *currZoneTotalFree = *sysZoneTotalFree = *tempZoneTotalFree = 0;
  446.     
  447.     return theErr;
  448. }
  449.  
  450. //--------------------------------------------------------------------- LargestHeap
  451.  
  452. static long LargestHeap (Size currZoneTotalFree, Size sysZoneTotalFree, 
  453.         Size tempZoneTotalFree)
  454. {
  455.     short        whichHeap;
  456.     
  457.     if (currZoneTotalFree >= sysZoneTotalFree)
  458.     {
  459.         if (currZoneTotalFree >= tempZoneTotalFree)
  460.             whichHeap = currentHeap;
  461.         else
  462.             whichHeap = tempHeap;
  463.     }
  464.     else
  465.     {
  466.         if (sysZoneTotalFree >= tempZoneTotalFree)
  467.             whichHeap = systemHeap;
  468.         else
  469.             whichHeap = tempHeap;
  470.     }
  471.     
  472.     return whichHeap;
  473. }
  474.  
  475. //--------------------------------------------------------------------- SetMem
  476.  
  477. static void SetMem (void *bytePtr, Size numBytes, UInt8 byteValue)
  478. {
  479.     register SInt32            i;
  480.     register SInt32            count;
  481.     register UInt8            *ptr;
  482.     register UInt8            value;
  483.     
  484.     count = numBytes;
  485.     ptr = (UInt8 *)bytePtr;
  486.     value = byteValue;
  487.     
  488.     for (i = 0; i < count; ++i)
  489.         *ptr++ = value;
  490. }
  491.  
  492.  
  493.